/**
 * Copyright © 2024, ZhiYun Network Co.,Ltd. All rights reserved.
 * ZhiYun PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */
package com.itcoon.cloud.framework.springdoc.config;

import com.itcoon.cloud.framework.properties.TemporalPatternConfigProperties;
import com.itcoon.cloud.framework.springdoc.enums.SecuritySchemeEnum;
import com.itcoon.cloud.framework.springdoc.plugin.*;
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.security.SecurityRequirement;
import io.swagger.v3.oas.models.security.SecurityScheme;
import io.swagger.v3.oas.models.servers.Server;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

import java.io.Serializable;

/**
 * Date: 10/6/24 10:57 PM
 * @author: miaoxia.yu
 * @version 1.0.0
 */
@EnableConfigurationProperties(SpringDocConfigProperties.class)
public class SpringDocConfig {

    private  final SpringDocConfigProperties properties;

    public SpringDocConfig(SpringDocConfigProperties properties) {
        this.properties = properties;
    }

    @Bean
    public OpenAPI openAPI(SpringDocConfigProperties docConfigProperties) {
        OpenAPI openAPI =  new OpenAPI();
        Server[] servers = properties.getServers();
        for(Server server : servers){
            openAPI.addServersItem(
                    new Server().url(server.getUrl()).description(server.getDescription())
            );
        }
        SecurityRequirement securityRequirement = new SecurityRequirement();
        Components components = new Components();
        for (SecuritySchemeEnum securityScheme : docConfigProperties.getSecuritySchemes()) {
            SecurityScheme scheme = securityScheme.getScheme(properties.getAuthorizationUrl(), properties.getTokenUrl(), properties.getOidcUrl(), properties.getScopesMap());
            scheme.name(securityScheme.getName());
            components.addSecuritySchemes(securityScheme.getName(), scheme);
            securityRequirement.addList(securityScheme.getName());
        }
        openAPI.components(components);
        openAPI.addSecurityItem(securityRequirement);
        openAPI.info(properties.getInfo());
        return openAPI;
    }

    @Bean
    public <V extends Serializable, E extends Enum<E>> BasicEnumPropertyCustomizer<V, E> basicEnumPropertyCustomizer(){
        return new BasicEnumPropertyCustomizer<>();
    }

    @Bean
    public <V extends Serializable, E extends Enum<E>> BasicEnumParameterCustomizer<V, E> basicEnumParameterCustomizer(){
        return new BasicEnumParameterCustomizer<>();
    }

    @Bean
    public TemporalParameterCustomizer temporalParameterCustomizer(TemporalPatternConfigProperties configProperties){
        return new TemporalParameterCustomizer(configProperties);
    }

    @Bean
    public TemporalPropertyCustomizer temporalPropertyCustomizer(TemporalPatternConfigProperties configProperties){
        return new TemporalPropertyCustomizer(configProperties);
    }

    @Bean
    public CollectionParameterCustomizer collectionParameterCustomizer(TemporalPatternConfigProperties configProperties){
        return new CollectionParameterCustomizer(configProperties);
    }

    @Bean
    public ArrayParameterCustomizer arrayParameterCustomizer(){
        return new ArrayParameterCustomizer();
    }

    @Bean
    public LongPropertyCustomizer longPropertyCustomizer(){
        return new LongPropertyCustomizer();
    }


}
